import { Callout } from "nextra-theme-docs";

# GZ::CTF

GZ::CTF 是一个基于 ASP.NET Core 的开源 CTF 平台，采用 Docker 或 K8s 作为容器部署后端，提供了可自定义的题目类型、动态容器和动态分值功能。

本项目缘起于作者认为 CTFd 的实现不优雅，动态容器配置需要采用插件的方式，且前端不好看，同时为了办校赛和帮助其他学校的同学办赛，于是自己动手写了一个。

GZ::CTF 基于 AGPLv3 协议开源，使用和修改均需遵守开源协议。开始部署请参考 [快速上手](/zh/quick-start)。

<Callout type="warning">

2024/01/01 起，`develop` 镜像的数据库结构不再与之前的版本兼容，如果继续使用请转至 `v0.17`。

在新特性的快速开发期，不建议使用 `develop` 镜像进行生产部署，相关数据库结构变更将导致数据丢失。

</Callout>

## 特性 🛠️

- 创建高度可自定义的题目

  - 题目类型：静态附件、动态附件、静态容器、动态容器

    - 静态附件：共用附件，任意添加的 flag 均可提交。
    - 动态附件：需要至少满足队伍数量的 flag 和附件，附件及 flag 按照队伍进行分发。
    - 静态容器：共用容器模版，不下发 flag，任意添加的 flag 均可提交。
    - 动态容器：自动生成并通过容器环境变量进行 flag 下发，每个队伍 flag 唯一。

  - 动态分值

    - 分值曲线：

      $$ f(S, r, d, x) = \left \lfloor S \times \left[r + ( 1- r) \times \exp\left( \dfrac{1 - x}{d} \right) \right] \right \rfloor $$

      其中 $S$ 为原始分值、 $r$ 为最低分值比例、 $d$ 为难度系数、 $x$ 为提交次数。前三个参数可通过自定义实现绝大部分的动态分值需求。

    - 三血奖励：
      平台对一二三血分别奖励 5%、3%、1% 的当前题目分值

  - 比赛进行中可启用、禁用题目，可多次放题
  - 动态 flag 中启用作弊检测，可选的 flag 模版，leet flag 功能

- **分组队伍**得分时间线、分组积分榜
- 基于 **Docker 或 K8s** 的动态容器分发、管理、多种端口映射方式
- 基于 SignalR 的**实时**比赛通知、比赛事件和 flag 提交监控及日志监控
- SMTP 邮件验证功能、基于 Google ReCaptchav3 的恶意注册防护
- 用户封禁、用户三级权限管理
- 可选的队伍审核、邀请码、注册邮箱限制
- 平台内 Writeup 收集、查阅、批量下载
- 可下载导出积分榜、可下载全部提交记录
- 比赛期间裁判监控、提交和主要事件日志
- 题目流量 **TCP over WebSocket 代理转发**、可配置流量捕获
- 基于 Redis 的集群缓存、基于 PGSQL 的数据库存储后端
- 面向 Prometheus / OpenTelemetry 的监控和数据追踪
- 全局配置项自定义、平台标题、备案信息
- 以及更多……

## Stars ✨

[![Stargazers over time](https://starchart.cc/GZTimeWalker/GZCTF.svg?variant=adaptive)](https://starchart.cc/GZTimeWalker/GZCTF)

## Grafana 📊

![grafana.webp](/images/grafana.webp)

## Demo 🗿

![index.webp](/images/index.webp)

![game.challenges.webp](/images/game.challenges.webp)

![game.scoreboard.webp](/images/game.scoreboard.webp)

![admin.settings.webp](/images/admin.settings.webp)

![admin.challenges.webp](/images/admin.challenges.webp)

![admin.challenge.info.webp](/images/admin.challenge.info.webp)

![admin.challenge.flags.webp](/images/admin.challenge.flags.webp)

![admin.game.info.webp](/images/admin.game.info.webp)

![admin.game.review.webp](/images/admin.game.review.webp)

![admin.teams.webp](/images/admin.teams.webp)

![admin.instances.webp](/images/admin.instances.webp)

![monitor.game.events.webp](/images/monitor.game.events.webp)

![monitor.game.submissions.webp](/images/monitor.game.submissions.webp)
